import hashlib
import secrets
from datetime import datetime, timedelta
from typing import Optional, Dict, Any
from jose import JWTError, jwt
from app.auth.models import User, UserInDB, Role
from app.utils.database import create_connection
from app.utils.config import settings

class AuthService:
    """鉴权服务类"""
    
    def __init__(self):
        self.SECRET_KEY = settings.SECRET_KEY if hasattr(settings, 'SECRET_KEY') else "your-secret-key-change-in-production"
        self.ALGORITHM = "HS256"
        self.ACCESS_TOKEN_EXPIRE_MINUTES = 30
    
    def verify_password(self, plain_password: str, hashed_password: str) -> bool:
        """验证密码"""
        # 使用简单的哈希方法（在生产环境中应使用更安全的方法如bcrypt）
        return hashlib.sha256(plain_password.encode()).hexdigest() == hashed_password
    
    def get_password_hash(self, password: str) -> str:
        """获取密码哈希值"""
        return hashlib.sha256(password.encode()).hexdigest()
    
    def authenticate_user(self, username: str, password: str) -> Optional[User]:
        """验证用户"""
        user = self.get_user(username)
        if not user:
            return None
        if not self.verify_password(password, user.hashed_password):
            return None
        return user
    
    def get_user(self, username: str) -> Optional[UserInDB]:
        """根据用户名获取用户"""
        conn = create_connection()
        cursor = conn.cursor()
        
        try:
            cursor.execute(
                "SELECT id, username, email, full_name, role_id, created_at, password_hash FROM users WHERE username = %s",
                (username,)
            )
            row = cursor.fetchone()
            if row:
                return UserInDB(
                    id=row[0],
                    username=row[1],
                    email=row[2],
                    full_name=row[3],
                    role_id=row[4],
                    is_active=True,  # 默认为活跃用户
                    created_at=row[5],
                    hashed_password=row[6]
                )
        except Exception as e:
            print(f"获取用户时出错: {e}")
        finally:
            cursor.close()
            conn.close()
        
        return None
    
    def get_role(self, role_id: int) -> Optional[Role]:
        """根据角色ID获取角色信息"""
        conn = create_connection()
        cursor = conn.cursor()
        
        try:
            cursor.execute(
                "SELECT id, name, description, permissions FROM roles WHERE id = %s",
                (role_id,)
            )
            row = cursor.fetchone()
            if row:
                return Role(
                    id=row[0],
                    name=row[1],
                    description=row[2],
                    permissions=row[3]
                )
        except Exception as e:
            print(f"获取角色时出错: {e}")
        finally:
            cursor.close()
            conn.close()
        
        return None
    
    def create_access_token(self, data: dict, expires_delta: Optional[timedelta] = None) -> str:
        """创建访问令牌"""
        to_encode = data.copy()
        if expires_delta:
            expire = datetime.utcnow() + expires_delta
        else:
            expire = datetime.utcnow() + timedelta(minutes=15)
        to_encode.update({"exp": expire})
        encoded_jwt = jwt.encode(to_encode, self.SECRET_KEY, algorithm=self.ALGORITHM)
        return encoded_jwt
    
    def create_user(self, user_data: dict) -> Optional[User]:
        """创建新用户"""
        conn = create_connection()
        cursor = conn.cursor()
        
        try:
            # 检查用户名是否已存在
            cursor.execute("SELECT id FROM users WHERE username = %s", (user_data['username'],))
            if cursor.fetchone():
                return None  # 用户名已存在
            
            # 插入新用户
            hashed_password = self.get_password_hash(user_data['password'])
            cursor.execute(
                """INSERT INTO users (username, email, full_name, password_hash, role_id, created_at) 
                   VALUES (%s, %s, %s, %s, %s, %s)""",
                (
                    user_data['username'],
                    user_data.get('email'),
                    user_data.get('full_name'),
                    hashed_password,
                    user_data['role_id'],
                    datetime.now()
                )
            )
            conn.commit()
            
            # 获取插入的用户ID
            user_id = cursor.lastrowid
            
            return User(
                id=user_id,
                username=user_data['username'],
                email=user_data.get('email'),
                full_name=user_data.get('full_name'),
                role_id=user_data['role_id'],
                is_active=True,  # 默认为活跃用户
                created_at=datetime.now()
            )
        except Exception as e:
            print(f"创建用户时出错: {e}")
            conn.rollback()
            return None
        finally:
            cursor.close()
            conn.close()

# 创建鉴权服务实例
auth_service = AuthService()